﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Sgr.Data;
using Sgr.EntityFrameworkCore.EntityConfigurations;
using Sgr.UPMS.Domain.Users;

namespace Sgr.UPMS.Infrastructure.EntityConfigurations
{
    internal class UserEntityTypeConfiguration : EntityTypeConfigurationBase<User, long>
    {
        public UserEntityTypeConfiguration(DatabaseType? databaseType = null) : base(databaseType)
        { }

        public override void Configure(EntityTypeBuilder<User> builder)
        {
            builder.ToTable("upms_user");

            base.Configure(builder);

            builder.PropertyAndHasColumnName(b => b.LoginName, GetColumnNameCase())
                .HasMaxLength(200)
                .IsRequired()
                .HasComment("登录名称");

            builder.PropertyAndHasColumnName(b => b.Gender, GetColumnNameCase())
                .IsRequired()
                .HasComment("性别");

            builder.PropertyAndHasColumnName(b => b.LoginPassword, GetColumnNameCase())
                .HasMaxLength(100)
                .IsRequired()
                .HasComment("登录密码");

            builder.PropertyAndHasColumnName(b => b.FirstLoginTime, GetColumnNameCase())
                .HasComment("首次登录时间");

            builder.PropertyAndHasColumnName(b => b.LastLoginTime, GetColumnNameCase())
                .HasComment("最近一次登录时间");

            builder.PropertyAndHasColumnName(b => b.LoginSuccessCount, GetColumnNameCase())
                .IsRequired()
                .HasComment("登录成功次数");

            builder.PropertyAndHasColumnName(b => b.FailedLoginAttempts, GetColumnNameCase())
                .IsRequired()
                .HasComment("连续登录失败次数");

            builder.PropertyAndHasColumnName(b => b.CannotLoginUntilUtc, GetColumnNameCase())
                .HasComment("禁止登录的截止时间");

            builder.PropertyAndHasColumnName(b => b.UserName, GetColumnNameCase())
                .HasMaxLength(200)
                .HasComment("用户姓名");

            builder.PropertyAndHasColumnName(b => b.UserPhone, GetColumnNameCase())
                .HasMaxLength(30)
                .HasComment("用户绑定的手机号码");

            builder.PropertyAndHasColumnName(b => b.IsPhoneVerified, GetColumnNameCase())
                .IsRequired()
                .HasDefaultValue(false)
                .HasComment("手机号是否已验证");

            builder.PropertyAndHasColumnName(b => b.QQ, GetColumnNameCase())
                .HasMaxLength(20)
                .HasComment("用户QQ号码");

            builder.PropertyAndHasColumnName(b => b.BirthDay, GetColumnNameCase())
                .HasComment("出生日期");

            builder.PropertyAndHasColumnName(b => b.UserEmail, GetColumnNameCase())
                .HasMaxLength(100)
                .HasComment("用户邮箱地址");

            builder.PropertyAndHasColumnName(b => b.IsEmailVerified, GetColumnNameCase())
                .IsRequired()
                .HasDefaultValue(false)
                .HasComment("邮箱是否已验证");

            builder.PropertyAndHasColumnName(b => b.WeChatOpenId, GetColumnNameCase())
                .HasMaxLength(255)
                .HasComment("微信OpenId");

            builder.PropertyAndHasColumnName(b => b.WeChatUnionId, GetColumnNameCase())
                .HasMaxLength(255)
                .HasComment("微信UnionId");

            builder.PropertyAndHasColumnName(b => b.IsSuperAdmin, GetColumnNameCase())
                .IsRequired();

            builder.PropertyAndHasColumnName(b => b.State, GetColumnNameCase())
                .IsRequired()
                .HasComment("状态");

            //部门
            builder.PropertyAndHasColumnName(b => b.DepartmentId, GetColumnNameCase())
                .HasComment("所属部门Id");

            builder.PropertyAndHasColumnName(b => b.DepartmentName, GetColumnNameCase())
                .HasMaxLength(200)
                .HasComment("所属部门名称");

            //首要岗位
            builder.PropertyAndHasColumnName(b => b.PrimaryDutyId, GetColumnNameCase())
                .HasComment("首要的岗位Id");

            builder.PropertyAndHasColumnName(b => b.PrimaryDeptName, GetColumnNameCase())
                .HasMaxLength(200)
                .HasComment("首要的岗位名称");

            //直接上级
            builder.PropertyAndHasColumnName(b => b.SuperiorUserId, GetColumnNameCase())
                .HasComment("直接上级用户Id");

            builder.PropertyAndHasColumnName(b => b.SuperiorUserName, GetColumnNameCase())
                .HasMaxLength(200)
                .HasComment("直接上级用户名称");

            builder.PropertyAndHasColumnName(b => b.MainAuthenticationType, GetColumnNameCase())
                .IsRequired()
                .HasDefaultValue(UserAuthenticationType.Password)
                .HasComment("主要身份验证类型");

            builder.PropertyAndHasColumnName(b => b.AuthenticatorKey, GetColumnNameCase())
                .HasMaxLength(255)
                .HasComment("双因素认证密钥");

            builder.PropertyAndHasColumnName(b => b.TwoFactorEnabled, GetColumnNameCase())
                .IsRequired()
                .HasDefaultValue(false)
                .HasComment("是否启用双因素认证");

            //职务
            builder.HasMany(b => b.Duties)
                .WithOne()
                .HasForeignKey("UserId")
                .OnDelete(DeleteBehavior.Cascade);

            builder.Metadata
                .FindNavigation(nameof(User.Duties))
                ?.SetPropertyAccessMode(PropertyAccessMode.Field);

            //角色
            builder.HasMany(b => b.Roles)
                .WithOne()
                .HasForeignKey("UserId")
                .OnDelete(DeleteBehavior.Cascade);

            builder.Metadata
                .FindNavigation(nameof(User.Roles))
                ?.SetPropertyAccessMode(PropertyAccessMode.Field);

            //设置索引
            base.AddOrgIndex(builder);

            builder.HasIndex(f => f.LoginName)
                .IsUnique()
                .HasDatabaseName("UK_User_LoginName");

            // 添加唯一索引
            builder.HasIndex(b => b.UserPhone)
                .IsUnique()
                .HasDatabaseName("UK_User_UserPhone");

            builder.HasIndex(b => b.UserEmail)
                 .IsUnique()
                 .HasDatabaseName("UK_User_UserEmail");

            builder.HasIndex(b => b.WeChatOpenId)
                .IsUnique()
                .HasDatabaseName("UK_User_WeChatOpenId");

            builder.HasIndex(b => b.WeChatUnionId)
                .IsUnique()
                .HasDatabaseName("UK_User_WeChatUnionId");
        }
    }
}